const fs = require('fs')
const path = require('path')
const childProcess = require('child_process')



/**
 * @name 命令仓库
 */
class CmdStore {

    constructor(options, msgHead) {
        this.commonOptions = {
            cwd: path.resolve(__dirname, './'),
            ...options
        }
        this.msgHead = msgHead || ''
        this.state = new Map()
    }

    waring(cmd, msg) {
        if (this.state.has(cmd)) {
            msg ? msg(cmd) : console.waring(`命令${cmd}已注册`.WARNING_COLOR)
            return true
        }
    }

    /**
     * @function 添加命令 
     */
    add(cmdName, options, msgHead) {
        if (this.waring(cmdName)) {
            return
        }

        if (typeof options === 'string' || !!!options) {
            msgHead = options
            options = {
                cmd: cmdName
            }
        }

        if (typeof cmdName === 'object') {
            options = cmdName.options || {}
            msgHead = cmdName.msgHead
            cmdName = cmdName.alias
        }
        this.state.set(cmdName, {
            cmd: options.cmd,
            options: options.options,
            msgHead
        })

        return this
    }

    /**
     * @function 打印信息
     * @param { string } msgHead 信息投
     */
    print(msgHead) {
        msgHead = msgHead || this.msgHead
        return data => console.log(`${msgHead.HEAD_COLOR}${data}`)
    }

    run(...args) {

        const _this = this;

        if (!args.length) {
            args = [...this.state.keys()]
        }


        args.forEach(prop => {

            if (!_this.state.has(prop)) {
                console.log(`命令${prop}未注册`.WARNING_COLOR)
                return
            }

            let {
                cmd,
                options,
                msgHead
            } = _this.state.get(prop)
            options = options || {}


            // 当命令问 node 函数模块时直接执行
            if (typeof cmd === 'function') {
                cmd()
                return
            }

            const cmdProcess = childProcess.exec(cmd, Object.assign({}, this.commonOptions, options))
            cmdProcess.stdout.on('data', this.print(msgHead))
        })

        return this
    }

    /**
     * @function 创建命令仓库
     * @param  {...any} args 
     */
    static create(...args) {
        return new CmdStore(...args)
    }
}

const store = CmdStore.create();

store.add({
    alias: 'log',
    options: {
        cmd: `echo hehe`
    },
    msgHead: 'test:'
})


module.exports = CmdStore